#pragma once

#include <atltheme.h>
#include "..\DataManager\ShortCutManager.h"

//#define ID_VIEW_THUMBNAILS              32772
//#define ID_VIEW_THUMBTEXT               32773
//#define ID_VIEW_TILES                   32774
#define WM_TOOLBOX_ACCEPTFILE          (WM_APP + 1100)

class CToolBoxListView : 
   public ATL::CWindowImpl<CToolBoxListView, WTL::CListViewCtrl>,
   public WTL::CTheme
{
public:
   DECLARE_WND_CLASS(_T("CToolBoxListView"))

   enum { CX_ICON_DEFAULT = 56 };

   WTL::CImageList m_Images;
   UINT m_uViewType;
   int m_cxIcon;
   ShortCutList* m_ShtList;
	int		m_nClassID;
   CToolBoxListView(int nClassID) : m_cxIcon(CX_ICON_DEFAULT), m_uViewType(ID_VIEW_THUMBTEXT)
   {
	   m_nClassID = nClassID;
	   CShortCutManager scM ;
	   m_ShtList = scM.Load(nClassID);
   }

   ~CToolBoxListView()
   { 
	  DeleteResource();
	   
   }
   void DeleteResource()
   {
	 //  DestroyWindow();
	    m_Images.Destroy();
	   if( NULL != m_ShtList)
	   {
		   POSITION pos = m_ShtList->GetHeadPosition();
		   while(NULL != pos)
		   {
			   ShortCut* pSC = m_ShtList->GetNext(pos);
			   if(NULL != pSC->m_pImage )
				   delete pSC->m_pImage ;
			   delete pSC;
		   }
		   delete m_ShtList;
	   }
   }
   BEGIN_MSG_MAP(CToolBoxListView)
      MESSAGE_HANDLER(WM_CREATE, OnCreate)
	  MSG_WM_LBUTTONDOWN(OnLButtonDown)
	  MSG_WM_MOUSEMOVE(OnMouseMove)
      MESSAGE_HANDLER(WM_INITMENUPOPUP, OnInitMenuPopup)
  /*    MESSAGE_HANDLER(WM_USER_ZOOM_CHANGE, OnZoomChange)      
      MESSAGE_HANDLER(WM_USER_IMAGE_NAVIGATE, OnImageNavigate)
      MESSAGE_HANDLER(WM_USER_VIEWMODE_CHANGE, OnViewModeChange)  */    
      COMMAND_ID_HANDLER(ID_VIEW_THUMBNAILS, OnViewModeChange)
      COMMAND_ID_HANDLER(ID_VIEW_THUMBTEXT, OnViewModeChange)

  	COMMAND_ID_HANDLER(ID_TBLIST_ADD, OnReSendCommond)
	COMMAND_ID_HANDLER(ID_TBLIST_DELETE_CATE, OnReSendCommond)
	COMMAND_ID_HANDLER(ID_TBLIST_RENAME_CATE, OnReSendCommond)
	COMMAND_ID_HANDLER(ID_TBLIST_SHORTCUT, OnReSendCommond)
	COMMAND_ID_HANDLER(ID_TBLIST_DELETE_SC, OnReSendCommond)
     // COMMAND_ID_HANDLER(ID_VIEW_TILES, OnViewModeChange)
      //COMMAND_ID_HANDLER(ID_VIEW_CONTENTS, OnViewTocChange)
      //COMMAND_ID_HANDLER(ID_VIEW_SELECTALL, OnViewSelectAll)
      REFLECTED_NOTIFY_CODE_HANDLER(LVN_ITEMCHANGED, OnItemChanged)
      REFLECTED_NOTIFY_CODE_HANDLER(NM_RCLICK, OnRightClick)
	  MSG_WM_DROPFILES(OnDropFiles)
   END_MSG_MAP()

   LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
   {
      LRESULT lRes = DefWindowProc();

      ModifyStyle(0, LVS_ALIGNTOP | LVS_SHAREIMAGELISTS|LVS_SINGLESEL);

      SetBkColor(RGB(238,243,250));
      SetTextBkColor(RGB(238,243,250));
      SetViewType(LV_VIEW_ICON);
      SetExtendedListViewStyle(LVS_EX_DOUBLEBUFFER, LVS_EX_DOUBLEBUFFER);
      if( IsThemingSupported() ) SetWindowTheme(m_hWnd, L"Explorer", NULL);
	  ModifyStyleEx(0,WS_EX_ACCEPTFILES);
      _PopulateList(TRUE);

      return lRes;
   }
   void RemoveShortCut(int item)
   {
	   ShortCut*	m_pSC = (ShortCut*)GetItemData(item);
		if(NULL != m_pSC)
		{
			CShortCutManager scm;
			scm.Delete(m_pSC->m_nID);
			DeleteItem(item);
			POSITION pos = m_ShtList->GetHeadPosition();
			while( NULL != pos)
			{
				POSITION curPos = pos;
				ShortCut* pSc = m_ShtList->GetNext(pos);
				if(pSc->m_nID == m_pSC->m_nID)
				{
					CShortCutManager scm;
					scm.Delete(pSc->m_nID);
					m_ShtList->RemoveAt(curPos);
					if(NULL != pSc->m_pImage)
						delete pSc->m_pImage;
					delete pSc;
					return;
				}
			}
		}
   }
	void OnDropFiles(HDROP hDropInfo)
	{
		UINT count;
		count = DragQueryFile(hDropInfo, 0xFFFFFFFF, NULL, 0);
		TCHAR filePath[MAX_PATH];
		if(count)
		{
			for(UINT i=0; i<count; i++)
			{
				int pathLen = ::DragQueryFile(hDropInfo, i, filePath, MAX_PATH);
				::SendMessage(GetParent().GetParent(),WM_TOOLBOX_ACCEPTFILE ,(WPARAM)filePath,0);
			}
		}
		DragFinish(hDropInfo); 

	}
   LRESULT OnInitMenuPopup(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
   {
      CWindow wndTop = GetTopLevelWindow();
      wndTop.SendMessage(uMsg, wParam, lParam);  // Allow MainFrm to UI-update the menu
      return 0;
   }
   void OnMouseMove(UINT uMsg,CPoint ptx)
   {
		LVHITTESTINFO hti;
		hti.pt = ptx;
		//::ClientToScreen(m_hWnd,&hti.pt );
		SubItemHitTest( &hti );
		HCURSOR   hc;


		if(hti.iItem > 0)
		{
			hc=LoadCursor(NULL,IDC_HAND);
			::SetCursor(hc);
		}
		else
		{
			hc=LoadCursor(NULL,IDC_ARROW);
			::SetCursor(hc);
		}
   }
	void OnLButtonDown(UINT uMsg, CPoint ptx)
	{
		BOOL	bHandle = FALSE;
		LVHITTESTINFO hti;
		hti.pt = ptx;
		//::ClientToScreen(m_hWnd,&hti.pt );
		SubItemHitTest( &hti );

		ShortCut* pSC = (ShortCut*)GetItemData(hti.iItem);
		if(NULL != pSC)
		{
			if(pSC->m_nType == 1)
				::ShellExecute(NULL,L"open",pSC->m_strAddress,NULL,NULL,SW_SHOW);
			if(pSC->m_nType == 2)
				::ShellExecute(NULL,L"explore",pSC->m_strAddress,NULL,NULL,SW_SHOW);
			if(pSC->m_nType == 3)
				::ShellExecute(NULL,L"open",pSC->m_strAddress,NULL,NULL,SW_SHOW);
			::ShowWindow(GetParent().GetParent(), SW_HIDE);
		}
		SetMsgHandled(bHandle);
	}

//   LRESULT OnZoomChange(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
//   {
//      int iZoom = (int) lParam;
//      BOOL bHighQuality = (wParam == 1);
//      _SetIconSize(iZoom);
//      _PopulateList(bHighQuality);
//      return 0;
//   }
//
   LRESULT OnViewModeChange(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
   {
      UINT uViewType = wID;
      SetFocus();
      _SetViewType(uViewType);
      _PopulateList(TRUE);
      return 0;
   }
   	LRESULT OnReSendCommond(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
	{
		::PostMessage(GetParent(),WM_COMMAND ,(WPARAM)wID,0);
		return 0L;
	}

//
//   LRESULT OnImageNavigate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
//   {
//#ifndef LVNI_VISIBLEORDER
//      const UINT LVNI_VISIBLEORDER     = 0x0010;
//      const UINT LVNI_PREVIOUS         = 0x0020;
//#endif // LVNI_VISIBLEORDER
//      SetFocus();
//      int iItem = GetNextItem(-1, LVNI_SELECTED);
//      iItem = GetNextItem(iItem, lParam == 1 ? LVNI_ALL|LVNI_VISIBLEORDER : LVNI_ALL|LVNI_VISIBLEORDER|LVNI_PREVIOUS);
//      SetItemState(-1, 0, LVIS_SELECTED | LVIS_FOCUSED);
//      SetItemState(iItem, LVIS_SELECTED | LVIS_FOCUSED, LVNI_SELECTED | LVIS_FOCUSED);
//      EnsureVisible(iItem, FALSE);
//      return 0;
//   }
//
//   LRESULT OnViewModeChange(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
//   {
//      _Photos.SendChangeNotify(WM_USER_VIEWMODE_CHANGE, wID);
//      return 0;
//   }
//
//   LRESULT OnViewTocChange(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
//   {
//      _Photos.SendChangeNotify(WM_USER_TOC_CHANGE);
//      return 0;
//   }

   LRESULT OnViewSelectAll(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
   {
      SetItemState(-1, LVIS_SELECTED, LVIS_SELECTED);
      return 0;
   }

   LRESULT OnItemChanged(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)
   {
     // CSimpleValArray<PHOTOINFO*> list;
     /* for( int iItem = GetNextItem(-1, LVNI_SELECTED); iItem != -1; iItem = GetNextItem(iItem, LVNI_SELECTED) ) {
         PHOTOINFO* pInfo = (PHOTOINFO*) GetItemData(iItem);
         if( pInfo == NULL ) continue;
         list.Add(pInfo);
      }*/
     // _Photos.SendChangeNotify(WM_USER_SELECTION_CHANGE, (WPARAM) list.GetSize(), (LPARAM) list.GetData());
      return 0;
   }

   LRESULT OnRightClick(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)
   {
	   CMenu menu;
	   menu.LoadMenu(IDR_TBLIST_MENU);
	   CMenuHandle submenu = menu.GetSubMenu(0);
	   CPoint pt(::GetMessagePos());
	   TrackPopupMenu(submenu, TPM_LEFTBUTTON, pt.x, pt.y, 0, m_hWnd, NULL);
	   return 0;
   }

   // Implementation

   void _SetViewType(UINT uType)
   {
      if( uType == 0 ) uType = ID_VIEW_THUMBTEXT;
      m_uViewType = uType;
   }

   void _SetIconSize(int cx)
   {
      if( cx <= 0 ) cx = CX_ICON_DEFAULT;
      m_cxIcon = cx;
   }

   void _PopulateList(BOOL bHighQualityThumbnails = TRUE)
   {
      USES_CONVERSION;
	
      bHighQualityThumbnails;
		if( NULL == m_ShtList)
			return;
      int cyIcon = m_cxIcon;//18 + (int)(m_cxIcon * 0.7);                                        // Height is proportionally less
      int cyOffset = 24;                                                              // Nice large gap at top
      double dblScale = 1.0;                                                          // Thumb is full scale
      if( m_uViewType == ID_VIEW_THUMBTEXT ) dblScale = 1.0;//0.8;                          // Thumb with text is slightly smaller
      //if( m_uViewType == ID_VIEW_TILES ) dblScale = 0.7, cyIcon -= 16, cyOffset = 2;  // Tiled mode have compact look

      SetRedraw(FALSE);

      DeleteAllItems();
   //   RemoveAllGroups();
      while( DeleteColumn(0) ) /* */;
      
      if( !m_Images.IsNull() ) m_Images.Destroy();
      m_Images.Create(m_cxIcon, cyIcon, ILC_COLOR32, m_ShtList->GetCount(), 0);
      SetImageList(m_Images, LVSIL_NORMAL);

      SetIconSpacing(m_cxIcon + 20, cyIcon + 26);

//      for( int iGroupId = 2020; iGroupId >= 1990; --iGroupId ) {
//         CString sGroup;
//         sGroup.Format(_T("%d"), iGroupId);
//         LVGROUP group;
//         group.cbSize = sizeof(LVGROUP);
//         group.mask = LVGF_HEADER | LVGF_GROUPID | LVGF_STATE;
//         group.pszHeader = const_cast<LPWSTR>(T2CW(sGroup));
//#ifndef LVGS_COLLAPSIBLE
//         const UINT LVGS_COLLAPSIBLE = 8;
//#endif // LVGS_COLLAPSIBLE
//         group.state = LVGS_COLLAPSIBLE;
//         group.stateMask = LVGS_COLLAPSIBLE;
//         group.iGroupId = iGroupId;
//         InsertGroup(-1, &group);
//      }
//
//      LVGROUPMETRICS gm = { 0 };
//      gm.cbSize = sizeof(gm);
//      gm.mask = LVGMF_TEXTCOLOR;
//      GetGroupMetrics(&gm);
//      gm.mask = LVGMF_TEXTCOLOR;
//      gm.crHeader = RGB(145,148,152);
//      SetGroupMetrics(&gm);
//
//      EnableGroupView(TRUE);

      /*if( m_uViewType == ID_VIEW_TILES ) {
         InsertColumn(0, _T("Title"));
         InsertColumn(1, _T("Date"));
         InsertColumn(2, _T("Size"));
         SetView(LV_VIEW_TILE);
         LVTILEVIEWINFO lvtvi = { 0 };
         lvtvi.cbSize = sizeof(LVTILEVIEWINFO);
         lvtvi.dwMask = LVTVIM_COLUMNS | LVTVIM_TILESIZE;
         lvtvi.dwFlags = LVTVIF_AUTOSIZE;
         lvtvi.cLines = 2;
         SetTileViewInfo(&lvtvi);
      }
      else {*/
         SetView(LV_VIEW_ICON);
    //  }
	  POSITION pos = m_ShtList->GetHeadPosition();
	  int iIndex = 0;
	  while( NULL != pos)
      {
		  ShortCut* pSc = m_ShtList->GetNext(pos);

         // Create thumbnail icon for imagelist
         CIcon icon;
         int cxThumb = (int)(m_cxIcon * dblScale);
         int cyThumb = (int)(cyIcon * dblScale);
		 Gdiplus::Image* pThumb = pSc->m_pImage->GetThumbnailImage(cxThumb, cyIcon);
		 Gdiplus::Image* pIcon = Gdiplus::Bitmap::FromHBITMAP(BkBmpPool::GetBitmap(IDB_TOOLBOX_ICON),NULL);
         if( pThumb != NULL ) {
            Gdiplus::Bitmap bm24bpp(cxThumb, cyThumb); 
            Gdiplus::Graphics g(&bm24bpp);
           // Gdiplus::Pen penShadow1(Gdiplus::Color(183,187,192));
           // Gdiplus::SolidBrush brBack(Gdiplus::Color(0,238,243,250));
           // Gdiplus::Rect rcThumb(0, 0, cxThumb, cyThumb);
           // g.FillRectangle(&brBack, rcThumb);
            //g.DrawRectangle(&penShadow1, 4, 4, cxThumb - 4, cyThumb -4);//cyThumb - cyOffset - 2);
			g.DrawImage(pIcon, 4, 4, cxThumb - 4, cyThumb -4);//cyThumb - cyOffset - 2);
            g.DrawImage(pThumb, (cxThumb - cyOffset)/2 , (cyThumb - cyOffset - 4)/2 , cxThumb - cyOffset, cyThumb - cyOffset ); 
           /* Gdiplus::Pen penWhite(Gdiplus::Color(255,255,255));
            Gdiplus::Pen penGrey(Gdiplus::Color(228,228,228));
            g.DrawRectangle(&penGrey, 2, 3, cxThumb - 3, cyThumb - 4);
            g.DrawRectangle(&penWhite, 1, 4, cxThumb - 4, cyThumb  - 4);
            g.DrawRectangle(&penWhite, 2, 5, cxThumb - 6, cyThumb  - 6);*/
            bm24bpp.GetHICON(&icon.m_hIcon);
            delete pThumb;
         }
         m_Images.AddIcon(icon);

        

         // Insert list item...
         LVITEM item = { 0 };
         item.iItem = iIndex;
         item.mask = LVIF_IMAGE | LVIF_PARAM ;//| LVIF_GROUPID;
         item.iImage = iIndex;
         if( m_uViewType == ID_VIEW_THUMBTEXT ) {
            item.mask |= LVIF_TEXT;
            item.pszText = (LPTSTR) static_cast<LPCTSTR>(pSc->m_strTitle);
         }
       /*  if( m_uViewType == ID_VIEW_TILES ) {
            item.mask |= LVIF_TEXT;
            item.pszText =(LPTSTR) static_cast<LPCTSTR>(pSc->m_strTitle);
         }*/
         item.lParam = (LPARAM) pSc;
		// item.iGroupId = pSc->m_nID;
         InsertItem(&item);
      
        /* if( m_uViewType == ID_VIEW_TILES ) {
            
			 SetItemText(item.iItem, 1, pSc->m_strAddress);
            UINT aCols[] = { 2, 1 };
            LVTILEINFO lvti = { sizeof(LVTILEINFO), item.iItem, sizeof(aCols) / sizeof(aCols[0]), aCols };
            SetTileInfo(&lvti);
         }*/
		 iIndex++;
      }

      SetItemState(0, LVIS_SELECTED, LVIS_SELECTED);
      SetRedraw(TRUE);
      Invalidate();
   }
};



